package com.jc.ecg;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.util.ArrayList;
import java.util.List;

/**
 * ==============================================
 * author : carl
 * e-mail : 991579741@qq.com
 * time   : 2018/11/27
 * desc   : 心电图
 * version: 1.0
 * ==============================================
 */
public class CarlECG extends SurfaceView implements SurfaceHolder.Callback, ICarlECG {
    private SurfaceHolder holder;
    //绘图线程
    private Thread thread;
    //绘图线程开关
    private Boolean isStart = false;
    //数据源1
    private List<Integer> data1 = new ArrayList<Integer>();
    //数据源2
    private List<Integer> data2 = new ArrayList<Integer>();
    //当前绘图数据源   1：数据源1  2：数据源2
    private int cResource = 1;
    //心电图画布宽高
    private int width, height;
    //心电图基线位置
    private int centerY;
    //绘图间隔
    private long delay = 40;

    //Y轴缩放程度
    private float yScale = 1f;
    //X轴速度
    private int speed = 4;
    //X轴开始画线位置
    private int startX = 0;

    //基线值
    private int baseLine = 0;

    //上一个坐标点的坐标值
    private int preX = 0;
    //上一个坐标点的坐标值
    private int preY = 0;

    //心电图画笔颜色
    private Paint linePaint = null;
    //黑板擦画笔
    private Paint clearPaint = null;

    //当前数值的坐标
    private int cIndex = 0;

    //背景图片
    private Bitmap bgMap = null;
    //缓存图片
    private Bitmap cacheMap = null;
    //背景画笔
    private Canvas bgCanvas = null;
    //设置背景颜色
    private int bgColor = Color.BLACK;
    //心电图最大值
    private int MAX = 100;
    //重置标识（内部使用）
    private boolean resetFlag = false;

    public CarlECG(Context context) {
        this(context, null);
    }

    public CarlECG(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CarlECG(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
        linePaint = new Paint();
        linePaint.setAntiAlias(true);
        linePaint.setStyle(Paint.Style.STROKE);
        linePaint.setColor(Color.RED);
        linePaint.setStrokeWidth(1);
        clearPaint = new Paint();
        clearPaint.setAntiAlias(true);
        clearPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        clearPaint.setStrokeWidth(1);
        clearPaint.setColor(bgColor);
        holder = getHolder();
        holder.addCallback(this);
    }

    @Override
    public void start() {
        startDraw();
    }

    @Override
    public void stop() {
        if (isStart) {
            isStart = false;
            if (null != thread) {
                thread.interrupt();
                thread = null;
            }
            cacheMap = bgMap.copy(Bitmap.Config.ARGB_8888, true);
        }
    }


    @Override
    public void reset() {
        preX = 0;
        startX = 0;
        resetFlag = true;
    }

    @Override
    public void toggle() {
        if (isStart) {
            stop();
        } else {
            start();
        }
    }

    @Override
    public void addData(List<Integer> temps, boolean drawNow) {
        if (drawNow) {
            if (cResource == 1) {//如果当前正在画数据源1
                data1.clear();
                data1.addAll(temps);
            } else {
                data2.clear();
                data2.addAll(temps);
            }
            cIndex = 0;
        } else {
            if (cResource == 1) {//如果当前正在画数据源1
                data2.clear();
                data2.addAll(temps);
            } else {
                data1.clear();
                data1.addAll(temps);
            }
        }
    }

    @Override
    public void setLineColor(int color) {
        linePaint.setColor(color);
    }

    @Override
    public void setLineWidth(int width) {
        linePaint.setStrokeWidth(width);
    }


    @Override
    public void setBgColor(int color) {
        bgColor = color;
    }

    @Override
    public void setLimitValue(int max) {
        MAX = max;
    }

    @Override
    public void setScaleY(float scale) {
        yScale = scale;
    }

    @Override
    public void setStepWidth(int stepWidth) {
        speed = stepWidth;
    }

    /**
     * 开启绘图线程
     */
    private void startDraw() {
        if (null != thread) {
            if (!thread.isInterrupted()) {
                thread.interrupt();
            }
            thread = null;
        }
        isStart = true;
        thread = new MyThread();
        thread.start();
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        width = getWidth();
        height = getHeight();
        centerY = height / 2;
        preY = centerY;
        bgMap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        bgCanvas = new Canvas(bgMap);
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        stop();
    }

    class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            long pre = 0;
            bgCanvas.drawColor(bgColor);
            clearPaint.setColor(bgColor);
            while (isStart) {
                Canvas canvas = holder.lockCanvas();
                if (null != cacheMap) {
                    bgCanvas.drawBitmap(cacheMap, 0, 0, null);
                    if (cacheMap != null && !cacheMap.isRecycled()) {
                        cacheMap.recycle();
                        cacheMap = null;
                    }
                }
                drawLine();
                canvas.drawBitmap(bgMap, 0, 0, null);
                holder.unlockCanvasAndPost(canvas);
                long current = System.currentTimeMillis();
                if ((current - pre) < delay) {
                    try {
                        Thread.sleep(delay - (current - pre));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                pre = System.currentTimeMillis();
            }
        }
    }

    /**
     * 画心电图
     */
    private void drawLine() {
        if (startX > width) {
            preX = 0;
            startX = 0;
        }
        int cY = (int) (centerY + (((1.0f * baseLine - getValue()) / MAX) * (height / 2) * yScale));
        bgCanvas.drawRect(startX, 0, startX + speed * 5, height, clearPaint);
        //重置-》清空图片
        if (resetFlag) {
            bgCanvas.drawColor(bgColor);
            resetFlag = false;
        }
        bgCanvas.drawLine(preX, preY, startX, cY, linePaint);
        preX = startX;
        preY = cY;
        startX += speed;
    }

    /**
     * 获取当前位置的值
     *
     * @return
     */
    private int getValue() {
        if (cResource == 1) {                        //当前数据源为1
            if (data1.isEmpty()) {                   //当前数据源为空
                cResource = 2;
                cIndex = 0;
                if (data2.isEmpty()) {               //如果数据源1和数据源2都为空-》返回0
                    return 0;
                } else {
                    int temp = data2.get(cIndex);
                    cIndex++;
                    if (cIndex >= data2.size()) {
                        cIndex = 0;
                    }
                    return temp;
                }
            }
            if (cIndex < data1.size()) {
                int temp = data1.get(cIndex);
                cIndex++;
                if (cIndex >= data1.size()) {
                    if (!data2.isEmpty()) {
                        cResource = 2;
                        data1.clear();
                    }
                    cIndex = 0;
                }
                return temp;
            }
        } else {                                      //当前数据源为2
            if (data2.isEmpty()) {
                cResource = 1;
                cIndex = 0;
                if (data1.isEmpty()) {
                    return 0;
                } else {
                    int temp = data1.get(cIndex);
                    cIndex++;
                    if (cIndex >= data1.size()) {
                        cIndex = 0;
                    }
                    return temp;
                }
            }
            if (cIndex < data2.size()) {
                int temp = data2.get(cIndex);
                cIndex++;
                if (cIndex >= data2.size()) {
                    if (!data1.isEmpty()) {
                        cResource = 1;
                        data2.clear();
                    }
                    cIndex = 0;
                }
                return temp;
            }
        }
        return 0;
    }

}
